/// <reference path="./textureBase.ts" />

namespace FIREFLYX {
    /**
     * 2D纹理 数组
     */
    export class Texture2DArray extends TextureBase {
        constructor(name: string = "", uuid?: string) {
            super(name, uuid);
            const gl = App.webgl2;
            // this.texelType = gl.UNSIGNED_BYTE;
            let glTex = gl.createTexture();
            if (glTex != null) this._glTextrue = glTex;
            this._paramSetting = new TextureParamSetting();
        }

        private _width: number = 0;
        private _height: number = 0;
        private _length: number = 0;
        private _paramSetting: TextureParamSetting;

        /** 参数设置 */
        public get paramSetting() { return this._paramSetting; }

        /** 纹理宽度 */
        public get width() { return this._width; }
        /** 纹理高度 */
        public get height() { return this._height; }
        /** 数组长度 */
        public get length() { return this._length; }

        public apply() {
            const gl = App.webgl2;
            TextureParamSetting.applyTex(gl.TEXTURE_2D_ARRAY, this._glTextrue, this._paramSetting);
        }

        /**
         * 设置纹理数据(纹理图像资源)
         * @param imgDatas 纹理图像资源
         */
        public setTextureData(imgDatas: TexImageSource[]): void;
        /**
         * 设置纹理数据
         * @param imgDatas 纹理二进制缓存
         * @param width 纹理宽度
         * @param height 纹理高度
         */
        public setTextureData(imgDatas: Uint8Array[], width: number, height: number): void;
        public setTextureData(imgDatas: (TexImageSource | Uint8Array)[], width?: number, height?: number): void {
            if (!imgDatas || imgDatas.length < 1) return;
            const gl = App.webgl2;
            const param = this._paramSetting;
            let oldUPA = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL) as boolean;
            let oldUFY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL) as boolean;
            //绑定指定纹理对象
            gl.bindTexture(gl.TEXTURE_2D_ARRAY, this._glTextrue);
            //像素存储参数设置
            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, param.premultiplyAlpha);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, param.flipY);
            const texLen = imgDatas.length;
            //

            let glFormat = param.getGLFormat();
            //上传纹理数据
            if (width == null || height == null) {
                let image = (imgDatas as TexImageSource[])[0];
                this._width = (image as any).width ?? 1;
                this._height = (image as any).height ?? 1;
            } else {
                this._width = width;
                this._height = height;
            }
            //
            gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, param.format, this._width, this._height, texLen, 0, glFormat, param.texelType, null);
            //填充subtex
            for (let i = 0; i < texLen; i++) {
                const tex = imgDatas[i];
                const w = width == null ? (tex as any).width ?? 1 : width;
                const h = height == null ? (tex as any).height ?? 1 : height;
                gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, i, w, h, 1, glFormat, param.texelType, tex as any);
            }

            //还原存储参数设置
            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, oldUPA);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, oldUFY);
            //解除绑定
            gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
        }

        /**
         * 设置 数组中子纹理数据(纹理图像资源)
         * @param imgData 纹理图像资源
         */
        public setSubTextureData(index: number, imgData: TexImageSource): void;
        /**
         * 设置 数组中子纹理数据
         * @param imgData 纹理二进制缓存
         */
        public setSubTextureData(index: number, imgData: Uint8Array): void;
        public setSubTextureData(index: number, imgData: TexImageSource | Uint8Array) {
            if (isNaN(index) || index < 0 || index > this._length) return;
            //
            const gl = App.webgl2;
            const param = this._paramSetting;
            let oldUPA = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL) as boolean;
            let oldUFY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL) as boolean;
            //绑定指定纹理对象
            gl.bindTexture(gl.TEXTURE_2D_ARRAY, this._glTextrue);
            //像素存储参数设置
            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, param.premultiplyAlpha);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, param.flipY);
            //

            let glFormat = param.getGLFormat();
            //设置subtex
            gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, index, this._width, this._height, 1, glFormat, param.texelType, imgData as any);

            //还原存储参数设置
            gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, oldUPA);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, oldUFY);
            //解除绑定
            gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
        }
    }
}